<?php
// +----------------------------------------------------------------------
// | SwiftPHP [ JUST DO ONE THING WELL ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2017  http://swiftphp.zhongwenyu.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhongwenyu <zhongwenyu1987@163.com> <http://www.zhongwenyu.com>
// +----------------------------------------------------------------------
// | Times: 2017/3/9 19:04
// +----------------------------------------------------------------------
namespace swift;

class Cache{

    // 连接池
    protected static $instance;
    // 统计缓存读出次数
    protected static $readnum;
    // 统计缓存写入次数
    protected static $writenum;

    // 本次操作
    protected static $handler = null;

    /**
     * 连接缓存
     * @access public
     * @param array         $options  配置数组
     * @param bool|string   $name 缓存连接标识 true 强制重新连接
     * @return Driver
     */
    public static function connect(array $options = [] , $name = false){
        // 缓存驱动
        $type = !empty($options['type']) ? $options['type'] : 'File';
        // 缓存连接唯一标识
        if(false === $name){
            $name = md5(serialize($options));
        }
        // 缓存初始化
        if(true === $name || !isset(self::$instance[$name])){
            $class = false !== strpos($type , '\\') ? $type : '\\swift\\cache\\driver\\' . ucfirst($type);

            if(true === $name){
                return new $class($options);
            }else{
                self::$instance[$name] = new $class($options);
            }
        }
        self::$handler = self::$instance[$name];
        return self::$handler;
    }

    /**
     * 自动初始化缓存
     * @access public
     * @param array         $options  配置数组
     * @return void
     */
    public static function init(array $options = []){
        if(is_null(self::$handler)){
            if(!empty($options)){
                self::connect($options);
            }elseif ('complex' == Config::get('cache.type')){
                self::connect(Config::get('cache.default'));
            }else{
                self::connect(Config::get('cache'));
            }
        }
    }

    /**
     * 切换缓存类型 需要配置 cache.type 为 complex
     * @access public
     * @param string $name 缓存标识
     * @return Driver
     */
    public static function store($name = '')
    {
        if ('' !== $name && 'complex' == Config::get('cache.type')) {
            if(strtolower($name) == 'file'){
                $option = Config::get('cache.default');
            }else{
                $option = Config::get($name);
            }
            if(empty($option)){
                throw new \Exception($name . ' 缓存未配置！');
            }
            self::connect($option, strtolower($name));
        }
        return self::$handler;
    }

    /**
     * 判断缓存是否存在
     * @access public
     * @param string $name 缓存变量名
     * @return bool
     */
    public static function has($name)
    {
        self::init();
        self::$readnum++;
        return self::$handler->has($name);
    }

    /**
     * 读取缓存
     * @access public
     * @param string $name 缓存标识
     * @param mixed  $default 默认值
     * @return mixed
     */
    public static function get($name, $default = false)
    {
        self::init();
        self::$readnum++;
        return self::$handler->get($name, $default);
    }

    /**
     * 写入缓存
     * @access public
     * @param string        $name 缓存标识
     * @param mixed         $value  存储数据
     * @param int|null      $expire  有效时间 0为永久
     * @return boolean
     */
    public static function set($name, $value, $expire = null)
    {
        self::init();
        self::$writenum++;
        return self::$handler->set($name, $value, $expire);
    }

    /**
     * 自增缓存（针对数值缓存）
     * @access public
     * @param string    $name 缓存变量名
     * @param int       $step 步长
     * @return false|int
     */
    public static function inc($name, $step = 1)
    {
        self::init();
        self::$writenum++;
        return self::$handler->inc($name, $step);
    }

    /**
     * 自减缓存（针对数值缓存）
     * @access public
     * @param string    $name 缓存变量名
     * @param int       $step 步长
     * @return false|int
     */
    public static function dec($name, $step = 1)
    {
        self::init();
        self::$writenum++;
        return self::$handler->dec($name, $step);
    }

    /**
     * 删除单个缓存
     * @access public
     * @param string    $name 缓存标识
     * @return boolean
     */
    public static function rm($name)
    {
        self::init();
        self::$writenum++;
        return self::$handler->rm($name);
    }

    /**
     * 清除缓存
     * @access public
     * @param string $tag 标签名
     * @return boolean
     */
    public static function clear($tag = null)
    {
        self::init();
        self::$writenum++;
        return self::$handler->clear($tag);
    }

    /**
     * 读取缓存并删除
     * @access public
     * @param string $name 缓存变量名
     * @return mixed
     */
    public static function pull($name)
    {
        self::init();
        self::$readnum++;
        self::$writenum++;
        return self::$handler->pull($name);
    }
}